class RtspNode {
  static Server = this.getServer(); // 服务器
  constructor(options) {
    this.Rtspurl = options.rtspURL;
    this.callback = options.callback;
    this.RemoteVideo = document.getElementById(options.remoteVideoElemtId);
    this.SendChannel = null;
    this.PC = new RTCPeerConnection();
    this.Interval = null;
    this.Offer = null;
    this.PC.onnegotiationneeded = e => this.handleNegotiationNeededEvent(e);
    this.PC.onicecandidate = e => this.onicecandidateEvent(e);
    this.PC.ontrack = e => this.ontrackEvent(e);
  }

  async handleNegotiationNeededEvent() {
    this.Offer = await this.PC.createOffer();
    await this.PC.setLocalDescription(this.Offer);
  }

  onicecandidateEvent(e) {
    const self = this;
    if (e.candidate == null) {
      $.post(RtspNode.Server + '/recive', {
        url: btoa(this.Rtspurl),
        data: btoa(this.PC.localDescription.sdp),
      })
        .done(data => {
          // console.log('recv receive response', data);
          if (data.result !== 'succ') {
            if (self.callback)
              self.callback({ data, elId: self.RemoteVideo.id }, self);
            console.log('onicecandidateEvent 播放失败', data.reason);
            return;
          }
          try {
            this.PC.setRemoteDescription(
              new RTCSessionDescription({
                type: 'answer',
                sdp: atob(data.data),
              })
            );
          } catch (e) {
            console.log(this.Rtspurl, data, atob(data));
          }
        })
        .fail(err => {
          console.log('onicecandidateEvent 播放失败', err);
        });
    }
  }

  ontrackEvent(e) {
    this.RemoteVideo.srcObject = e.streams[0];
    this.RemoteVideo.muted = true;
    this.RemoteVideo.autoplay = true;
    // this.RemoteVideo.controls = false;
    // this.RemoteVideo.width = 640;
  }
  /**
   * 播放
   */
  play() {
    const self = this;
    $.post(RtspNode.Server + '/play', {
      url: btoa(self.Rtspurl),
    })
      .done(data => {
        if (self.callback)
          self.callback({ data, elId: self.RemoteVideo.id }, self);
        // console.log('add video Transceiver', data);
        if (data.result !== 'succ') {
          console.log('rtspPlay播放失败', data.reason, self.Rtspurl);
          return;
        }
        self.PC.addTransceiver('video', {
          direction: 'sendrecv',
        });

        self.SendChannel = self.PC.createDataChannel('foo');
        self.SendChannel.onclose = event => {
          if (self.callback)
            self.callback({ event, elId: self.RemoteVideo.id }, self);
          console.log('sendChannel has closed');
          if (self.Interval != null) {
            clearInterval(self.Interval);
            self.Interval = null;
          }
        };
        self.SendChannel.onopen = event => {
          if (self.callback)
            self.callback({ event, elId: self.RemoteVideo.id }, self);
          console.log('sendChannel has opened');
          self.SendChannel.send('Keep-Alive');
          self.Interval = setInterval(function() {
            self.SendChannel.send('Keep-Alive');
            // console.log("keep-Alive");
          }, 3000);
        };
        self.SendChannel.onmessage = event => {
          console.log('Message from DataChannel: payload ' + event.data);
        };
      })
      .fail(err => {
        console.log('播放失败 rtspPlay', err);
        if (self.callback)
          self.callback(
            {
              data: { result: 'fail' },
              elId: self.RemoteVideo.id,
            },
            self
          );
      });
  }

  /**
   * 初始化
   * @param {String} server 服务器
   */
  static init(server) {
    this.Server = server;
  }

  // 获取服务器
  static getServer() {
    return `${location.origin}/rtspplay`;
  }
}

const playRtsp = (rtspURL, remoteVideoElemtId, callback) => {
  let rtspNode = new RtspNode({ rtspURL, remoteVideoElemtId, callback });
  rtspNode.play();
  return rtspNode;
};

export default playRtsp;
